import IpcParams from "../IpcParams";
import { createAgent } from './utils';
import Axios from 'axios';
import axiosRetry from 'axios-retry';
const stringUtil = require('@/utils/string')

export default class DuckchainGame {
  constructor(tokenInfo) {
    this.tokenInfo = tokenInfo
    const agent = createAgent(this.tokenInfo.proxy)
    const headers = {
      // "Referer": "https://hamsterkombatgame.io/",
      "User-Agent": "Mozilla/5.0 (iPhone; CPU iPhone OS 16_7_2 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Mobile/15E148",
    }
    this.axios = Axios.create({
      headers: headers,
      httpAgent: agent,
      httpsAgent: agent,
    })
    axiosRetry(this.axios, {
      retries: 3, retryDelay: (retryCount) => {
        return 2000
      }
    });
  }

  async run() {
    try {
      const axios = this.axios
      let webSessionUrl = this.tokenInfo.tgweb
      const req_header = await this.get_req_header(webSessionUrl)
      const inviteUrl = this.tokenInfo.inviteUrl
      let refId = "0ZWSgUUQ"
      if (inviteUrl != null) {
        refId = inviteUrl.split("startapp=")[1]
      }
      // Try to register, if already registed will got code 500 and an error message. But just ignore it currently.
      await axios.get('https://preapi.duckchain.io/user/info', {
        headers: req_header
      })
        .then(response => {
          if (response.data.data.duckName == '' || response.data.data.duckName == null) {
            // register
            console.log('try to register ')
            let user_name = webSessionUrl.slice(webSessionUrl.indexOf('first_name') + 25, webSessionUrl.indexOf('last_name') - 15)
            user_name = user_name.replace(/[&\/\\#,+()$~%.'":*?<>{}]/g,'');
            user_name = user_name + stringUtil.random_str(8)
            // https://preapi.duckchain.io/user/set_duck_name?duckName=Tim%20Jeffersonesines1
            axios.get('https://preapi.duckchain.io/user/set_duck_name?duckName=' + user_name, {
              headers: req_header
            }).then(response => {
              // console.log(response)
            }).catch(function (error) {
              console.log(error)
            })

            //https://preapi.duckchain.io/user/bind_invite?inviteCode=0ZWSgUUQ
            axios.get(`https://preapi.duckchain.io/user/bind_invite?inviteCode=${refId}`, {
              headers: req_header
            }).then(response => {
              // console.log(response)
            }).catch(function (error) {
              console.log(error)
            })

          } else {
            console.log('user already registed')
          }
        })
        .catch(function (error) {
          if (error.response == null) {
            console.error(error)
          } else {
            console.log(error.response.data.message)
            if (error.response.data.message.indexOf('is already connected to another user') > 0) {
              console.log('The account already registed.')
            }
          }
        })

      const sleepNow = (delay) => new Promise((resolve) => setTimeout(resolve, delay))

      /* start works */

      /* 1. Sign in */
      // https://preapi.duckchain.io/task/sign_in
      await axios.get('https://preapi.duckchain.io/task/sign_in', {
        headers: req_header
      }).then(response => {
        // console.log(response)
      }).catch(function (error) {
        console.log(error)
      })


      /* 2. Tasks */
      let tasks_objs = [];
      await axios.get('https://preapi.duckchain.io/task/task_list', {
        headers: req_header
      }).then(response => {

        // social_media, daily, oneTime, partner
        response.data.data.social_media.forEach(function (social_media_key, social_media_value) {
          // console.log('sleep while : ', social_media_key)
          tasks_objs.push(social_media_key)
        })

        response.data.data.daily.forEach(function (daily_key, daily_value) {
          tasks_objs.push(daily_key)
        })

        response.data.data.oneTime.forEach(function (oneTime_key, oneTime_value) {
          tasks_objs.push(oneTime_key)
        })

        response.data.data.partner.forEach(function (partner_key, partner_value) {
          tasks_objs.push(partner_key)
        })
      }).catch(function (error) {
        console.log(error)
      })

      for (let i = 0; i < tasks_objs.length; i++) {
        const task_key = tasks_objs[i]

        // console.log('sleep 2000, follow_twitter', tasks_objs[i].taskId)
        await sleepNow(4000)

        axios.get('https://preapi.duckchain.io/task/follow_twitter?taskId=' + task_key.taskId, {
          headers: req_header
        }).then(response => {
          // console.log(response)
        }).catch(function (error) {
          // console.log(error)
        })

        // console.log('sleep 2000, twitter_interaction', tasks_objs[i].taskId)
        await sleepNow(4000)

        axios.get('https://preapi.duckchain.io/task/twitter_interaction?taskId=' + task_key.taskId, {
          headers: req_header
        }).then(response => {
          // console.log(response)
        }).catch(function (error) {
          console.log(error)
        })

        // console.log('sleep 3000, partner', tasks_objs[i].taskId)
        await sleepNow(6000)

        axios.get('https://preapi.duckchain.io/task/partner?taskId=' + task_key.taskId, {
          headers: req_header
        }).then(response => {
          // console.log(response)
        }).catch(function (error) {
          console.log(error)
        })
      }

      /* update user balance  */
      // console.log("=======  availableBalance   ======>>> ")
      const response = await axios.get('https://preapi.duckchain.io/user/info', {
        headers: req_header
      })
      //response.data.data.duckName
      const user_balance = response.data.data.decibels
      const date = (new Date()).toLocaleString()
      this.tokenInfo.score = user_balance
      this.tokenInfo.gameupdate = date
      this.tokenInfo.count = (this.tokenInfo.count || 0) + 1
      console.log(date, "duckchain end", this.tokenInfo.phone, "score: ", this.tokenInfo.score)
      return new IpcParams("runDuckchain", this.tokenInfo)
    } catch (error) {
      const date = (new Date()).toLocaleString()
      console.log(date, "duckchain error", this.tokenInfo.phone)
      console.error(error)
      return new IpcParams("runDuckchain", this.tokenInfo, error)
    }
  }

  async get_req_header(webSessionUrl) {
    if (webSessionUrl.startsWith("https://") == false) {
      console.error(`${this.tokenInfo.phone}  error session url ${webSessionUrl}`);
      return
    }
    let decodedWebSessionUrl = decodeURIComponent(webSessionUrl)
    let session = decodedWebSessionUrl.split("#tgWebAppData=")[1]
    session = session.split("&tgWebAppVersion")[0]

    // if ( session.indexOf('username') <= 0) { // At the first time, we need check if the user registed. If the URL value has not inclulded username value, it means the current account has not registed. Need register first. 
    let user_name = session.slice(session.indexOf('first_name') + 19, session.indexOf('last_name') - 9)
    user_name = user_name.replace(/[&\/\\#,+()$~%.'":*?<>{}]/g,'');
    user_name = user_name + stringUtil.random_str(8)

    const req_header = {
      'content-type': 'application/json',
      authorization: 'tma ' + session
    }

    return req_header
  }
}